package io.gitee.kotle.android.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import androidx.viewpager2.widget.ViewPager2
import io.gitee.kotle.android.R
import io.gitee.kotle.android.utils.dp
import io.gitee.kotle.android.widget.BaseView
import java.lang.IllegalStateException

open class ViewPager2IndicatorView : BaseView {
    private var orientation: Int = ViewPager2.ORIENTATION_HORIZONTAL
    private var currentPosition: Int = 0
    private val rect = RectF()
    private val overRect = RectF()
    private var currentPositionOffset: Float = 0f
    private val paint = Paint().also {
        it.isAntiAlias = true
    }

    /**
     * 每一页的变化指示器需要移动的值
     */
    private var itemOffSet = 0f

    private var itemCount = 0
        set(value) {
            field = value
            if (itemCount > 1) {
                itemOffSet = when (orientation) {
                    ViewPager2.ORIENTATION_VERTICAL -> {
                        if (indicatorMargin > 0) {
                            indicatorSize =
                                (height - ((itemCount - 1) * indicatorMargin)) / itemCount
                            indicatorSize + indicatorMargin
                        } else {
                            (height - indicatorSize) / (itemCount - 1) + indicatorMargin
                        }
                    }
                    ViewPager2.ORIENTATION_HORIZONTAL -> {
                        if (indicatorMargin > 0) {
                            indicatorSize =
                                (width - ((itemCount - 1) * indicatorMargin)) / itemCount
                            indicatorSize + indicatorMargin
                        } else {
                            (width - indicatorSize) / (itemCount - 1) + indicatorMargin
                        }
                    }
                    else -> {
                        throw IllegalStateException("orientation is unknow")
                    }
                }
            }
        }

    /**
     * 指示器宽度
     */
    var indicatorSize = 16f.dp

    /**
     * 指示器颜色
     */
    var indicatorColor = Color.parseColor("#003333")

    /**
     * 指示器背景颜色
     */
    var indicatorBgColor = Color.RED

    /**
     * 指示器间距
     */
    var indicatorMargin = 4f.dp

    /**
     * 指示器圆角
     */
    var indicatorRadius = 5f.dp

    /**
     * 手动强制设置itemCount，如果不为null，则优先使用这个
     */
    var overrideItemCount: Int? = null

    constructor(context: Context) : this(context, null)
    constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    ) {
        context.obtainStyledAttributes(attrs, R.styleable.ViewPager2IndicatorView).apply {
            indicatorBgColor =
                getColor(R.styleable.ViewPager2IndicatorView_vp2IndicatorBgColor, indicatorBgColor)
            indicatorColor =
                getColor(R.styleable.ViewPager2IndicatorView_vp2IndicatorColor, indicatorColor)
            indicatorRadius =
                getDimension(
                    R.styleable.ViewPager2IndicatorView_vp2IndicatorRadius,
                    indicatorRadius
                )
            indicatorSize =
                getDimension(R.styleable.ViewPager2IndicatorView_vp2IndicatorSize, indicatorSize)
            indicatorMargin =
                getDimension(
                    R.styleable.ViewPager2IndicatorView_vp2IndicatorMargin,
                    indicatorMargin
                )
        }.recycle()
    }

    fun setUpWith(vp2: ViewPager2) {
        orientation = vp2.orientation
        vp2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
                super.onPageScrolled(position, positionOffset, positionOffsetPixels)
                orientation = vp2.orientation
                val realItemCount = overrideItemCount ?: vp2.adapter?.itemCount ?: 0
                if (realItemCount != 0) {
                    itemCount = realItemCount
                    updateIndicator(position % realItemCount, positionOffset)
                }
            }
        })
    }


    /**
     * 更新指示器位置
     */
    private fun updateIndicator(position: Int, positionOffset: Float) {
        currentPosition = position
        currentPositionOffset = positionOffset
        invalidate()
    }

    fun refreshIndicator(vp2: ViewPager2) {
        vp2.post {
            val realItemCount = overrideItemCount ?: vp2.adapter?.itemCount ?: 0
            if (realItemCount != 0) {
                itemCount = realItemCount
                updateIndicator(vp2.currentItem % realItemCount, 0f)
            }
        }
    }


    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (itemCount > 1) {
            drawBg(canvas, orientation)
            paint.color = indicatorColor
            when (orientation) {
                ViewPager2.ORIENTATION_VERTICAL -> {
                    rect.top =
                        itemOffSet * (currentPositionOffset + currentPosition) + currentPosition
                    rect.bottom = rect.top + indicatorSize
                    rect.left = 0f
                    rect.right = width.toFloat()
                    val off = rect.bottom - height
                    if (off > 0) {
                        //溢出
                        rect.bottom = height.toFloat()
                        overRect.set(0f, 0f, rect.right, off - (itemOffSet - indicatorSize))
                        canvas.drawRoundRect(overRect, indicatorRadius, indicatorRadius, paint)
                    }
                }
                ViewPager2.ORIENTATION_HORIZONTAL -> {
                    rect.top = 0f
                    rect.bottom = height.toFloat()
                    rect.left = itemOffSet * (currentPositionOffset + currentPosition)
                    rect.right = rect.left + indicatorSize
                    val off = rect.right - width
                    if (off > 0) {
                        //溢出
                        rect.right = width.toFloat()
                        overRect.set(0f, 0f, off - (itemOffSet - indicatorSize), rect.bottom)
                        canvas.drawRoundRect(overRect, indicatorRadius, indicatorRadius, paint)
                    }
                }
                else -> {
                    return
                }
            }
            canvas.drawRoundRect(rect, indicatorRadius, indicatorRadius, paint)
        }
    }

    private fun drawBg(canvas: Canvas, orientation: Int) {
        if (indicatorMargin <= 0) {
            rect.top = 0f
            rect.bottom = height.toFloat()
            rect.left = 0f
            rect.right = width.toFloat()
            paint.color = indicatorBgColor
            canvas.drawRoundRect(rect, indicatorRadius, indicatorRadius, paint)
            return
        }
        repeat(itemCount) {
            when (orientation) {
                ViewPager2.ORIENTATION_VERTICAL -> {
                    rect.top = (indicatorSize + indicatorMargin) * it
                    rect.bottom = rect.top + indicatorSize
                    rect.left = 0f
                    rect.right = width.toFloat()
                }
                ViewPager2.ORIENTATION_HORIZONTAL -> {
                    rect.top = 0f
                    rect.bottom = height.toFloat()
                    rect.left = (indicatorSize + indicatorMargin) * it
                    rect.right = rect.left + indicatorSize
                }
                else -> {
                    return
                }
            }
            paint.color = indicatorBgColor
            canvas.drawRoundRect(rect, indicatorRadius, indicatorRadius, paint)
        }
    }
}